import sys
import json

sys.path.append("../..")

from common.tools.dbc_reader import dbcReader

class CodeGenerator:

    def make_CAN_SIGNAL_INDEX(self, dst):
        print("/// [GENERATION-BEGIN] [CAN-SIGNAL-INDEX]", file=dst)
        print("enum CanSignalIndex", file=dst)
        print("{", file=dst)
        count = 0
        for signal in dbcReader.signal_list:
            print("    %s = %d," % (signal.fullname, count), file=dst)
            count += 1
        print("", file=dst)
        print("    TOTAL_NUMBERS = %d" % count, file=dst)
        print("}", file=dst)
        print("/// [GENERATION-END] [CAN-SIGNAL-INDEX]", file=dst)

    def make_CAN_SIGNAL_DESC(self, dst):
        print("/// [GENERATION-BEGIN] [CAN-SIGNAL-DESC] { frame_id, start_pos, bit_length }", file=dst)
        print("#define  CAN_SIGNAL_DESC  \\", file=dst)
        count = 0
        for signal in dbcReader.signal_list:
            print("    { %d, %d, %d }, /* %s */  \\" % (signal.frame_id, signal.start_pos, signal.bit_length, signal.fullname), file=dst)
            count += 1
        print("", file=dst)
        print("/// [GENERATION-END] [CAN-SIGNAL-DESC]", file=dst)

    def make_CAN_FRAME_INDEX(self, dst):
        print("/// [GENERATION-BEGIN] [CAN-FRAME-INDEX]", file=dst)
        print("enum CanFrameIndex", file=dst)
        print("{", file=dst)
        count = 0
        for frame in dbcReader.frame_list:
            print("    %s = %d," % (frame.name, count), file=dst)
            count += 1
        print("", file=dst)
        print("    TOTAL_NUMBERS = %d" % count, file=dst)
        print("}", file=dst)
        print("/// [GENERATION-END] [CAN-FRAME-INDEX]", file=dst)

    def make_CAN_FRAME_DESC(self, dst):
        print("/// [GENERATION-BEGIN] [CAN-FRAME-DESC] { frame_id, frame_index, frame_data_length }", file=dst)
        print("#define  CAN_FRAME_DESC  \\", file=dst)
        count = 0
        for frame in dbcReader.frame_list:
            print("    { %d, %d, %d }, /* %s */  \\" % (frame.id, count, frame.length, frame.name), file=dst)
            count += 1
        print("", file=dst)
        print("/// [GENERATION-END] [CAN-FRAME-DESC]", file=dst)

    def make_CAN_FRAME_SIGNAL(self, dst):
        print("/// [GENERATION-BEGIN] [CAN-FRAME-SIGNAL] {frame id, first signal index}", file=dst)
        print("#define  CAN_FRAME_SIGNAL  \\", file=dst)
        frame_id = -1
        count = 0
        for signal in dbcReader.signal_list:
            if frame_id != signal.frame_id:
                frame_id = signal.frame_id
                print("    { %d, %d },  \\" % (signal.frame_id, count), file=dst)
            count += 1
        print("", file=dst)
        print("/// [GENERATION-END] [CAN-FRAME-SIGNAL]", file=dst)

    def make_SDB_SIGNAL_DESC(self, dst):
        print("/// [GENERATION-BEGIN] [SDB-SIGNAL-DESC]", file=dst)
        print("#define  SDB_SIGNAL_DESC  \\", file=dst)
        count = 0
        for signal in dbcReader.signal_list:
            print("/* %s */ \\" % signal.fullname, file=dst)
            print("{SdbSignalId_T::makeKey(%d, %d, %d), {%d, %d, %d, ESignalClass::SIGNAL,	EUpdateFrom::CLIENT_AND_SERVER,	0,	ESignalDirection::TX}}, \\" %
                  (signal.frame_id, signal.start_pos, signal.bit_length,
                   signal.frame_id, signal.start_pos, signal.bit_length),
                  file=dst)
        print("", file=dst)
        print("/// [GENERATION-END] [SDB-SIGNAL-DESC]", file=dst)

    def generate(self, src_file, dst_file):
        print("generate from {%s} to {%s}" % (src_file, dst_file))
        # open files
        src = open(src_file, 'r')
        dst = open(dst_file, 'w')

        # read 1st line
        line = src.readline()
        while line != '':
            info = line.split()
            if len(info) > 0 and info[0] == '///' and info[1] == '[TO-BE-GENERATED]':
                # generate code
                if info[2] == '[CAN-FRAME-INDEX]':
                    self.make_CAN_FRAME_INDEX(dst)
                elif info[2] == '[CAN-FRAME-DESC]':
                    self.make_CAN_FRAME_DESC(dst)
                elif info[2] == '[CAN-FRAME-SIGNAL]':
                    self.make_CAN_FRAME_SIGNAL(dst)
                elif info[2] == '[CAN-SIGNAL-INDEX]':
                    self.make_CAN_SIGNAL_INDEX(dst)
                elif info[2] == '[CAN-SIGNAL-DESC]':
                    self.make_CAN_SIGNAL_DESC(dst)
                elif info[2] == '[SDB-SIGNAL-DESC]':
                    self.make_SDB_SIGNAL_DESC(dst)
            else:
                # directly copy
                print(line[:-1], file=dst)
            # read next line
            line = src.readline()

        # close files
        dst.close()
        src.close()


codeGenerator = CodeGenerator()


